package org.jeecg.modules.shiro;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.jeecg.common.util.RedisUtil;
import org.jeecg.modules.wechat.entity.WxUser;
import org.jeecg.modules.wechat.mapper.WxUserMapper;
import org.jeecg.modules.wechat.service.IWxUserService;
import org.springframework.beans.factory.annotation.Autowired;

/**
 * TODO: shiro授权和认证
 *
 * @author Zhang Hao yu
 * @date 2020/11/12 21:16
 */
public class WxUserRealm extends AuthorizingRealm {

    @Autowired
    private WxUserMapper wxUserMapper;

    @Autowired
    private IWxUserService wxUserService;

    @Autowired
    private RedisUtil redisUtil;
    /**
     * TODO: 检查是否支持该Realm，一定要重写support方法，后面的身份验证器中会用到
     *
     *
     * @author ZhangHaoyu
     * @param token
     * @return boolean
     */
    @Override
    public boolean supports(AuthenticationToken token) {
        return token instanceof WxUserToken;
    }

    /**
     * TODO: 授权
     *
     *
     * @author ZhangHaoyu
     * @param principalCollection
     * @return org.apache.shiro.authz.AuthorizationInfo
     */
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        WxUser wxUser = (WxUser) SecurityUtils.getSubject().getPrincipal();
        SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();
        return authorizationInfo;
    }

    /**
     * TODO: 认证，在这个方法中完成老用户登录和新用户注册
     *
     *
     * @author ZhangHaoyu
     * @param authenticationToken
     * @return org.apache.shiro.authc.AuthenticationInfo
     */
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
        WxUserToken token = (WxUserToken) authenticationToken;
        WxUser authUser = token.getUser();
        if (authUser == null){
            throw new AuthenticationException();
        }
        // 获取openId
        String openId = authUser.getOpenId();
        WxUser user = wxUserMapper.selectOne(new LambdaQueryWrapper<WxUser>().eq(WxUser::getOpenId, openId));
        WxUser wxUser = null;
        if (user == null){
            // 进行注册
            String rawData = token.getRawData();
            JSONObject userInfo = JSONObject.parseObject(rawData);
            // 保存数据库
            wxUser = wxUserService.saveUserByJsonObject(userInfo, openId);
            // redis中记录用户的积分
//            redisUtil.incrBy(RedisConstant.USER_SCORE+openId,0);
        }else {
            wxUser = user;
        }
        token.setUser(wxUser);
        // 传 principal和credentials
        SimpleAuthenticationInfo authenticationInfo = new SimpleAuthenticationInfo(user,openId,"WX_REALM");
        return authenticationInfo;
    }
}